home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / c-lang / vbcc.lha / vbcc / ic.c < prev    next >
C/C++ Source or Header  |  1996-05-15  |  43KB  |  1,197 lines

  1. /*  $VER: vbcc (ic.c) V0.3  */
  2.  
  3. #include "vbc.h"
  4.  
  5. struct IC *first_ic=0,*last_ic=0;
  6. int float_used;
  7.  
  8. int do_arith(np,struct IC *,np,struct obj *);
  9.  
  10. void inline_memcpy(np z,np q,zulong size)
  11. /*  fuegt ein ASSIGN-IC ein, das memcpy(z,q,size) entspricht    */
  12. {
  13.     struct IC *new=mymalloc(ICS);
  14.     if((z->ntyp->flags&15)!=POINTER) ierror(0);
  15.     if((q->ntyp->flags&15)!=POINTER) ierror(0);
  16.  
  17.     gen_IC(z,0,0);
  18.     if(z->o.flags&DREFOBJ){
  19.         struct IC *n2=mymalloc(ICS);
  20.         n2->code=ASSIGN;
  21.         n2->typf=q->ntyp->flags;
  22.         n2->q1=z->o;
  23.         get_scratch(&n2->z,z->ntyp->flags,z->ntyp->next->flags);
  24.         n2->q2.flags=0;
  25.         n2->q2.reg=sizetab[POINTER];
  26.         new->z=n2->z;
  27.         add_IC(n2);
  28.     }else{
  29.         new->z=z->o;
  30.     }
  31.     if(new->z.flags&VARADR) new->z.flags&=~VARADR; else new->z.flags|=DREFOBJ;
  32.  
  33.     gen_IC(q,0,0);
  34.     if(q->o.flags&DREFOBJ){
  35.         struct IC *n2=mymalloc(ICS);
  36.         n2->code=ASSIGN;
  37.         n2->typf=q->ntyp->flags;
  38.         n2->q1=q->o;
  39.         get_scratch(&n2->z,q->ntyp->flags,q->ntyp->next->flags);
  40.         n2->q2.flags=0;
  41.         n2->q2.reg=sizetab[POINTER];
  42.         new->q1=n2->z;
  43.         add_IC(n2);
  44.     }else{
  45.         new->q1=q->o;
  46.     }
  47.     if(new->q1.flags&VARADR) new->q1.flags&=~VARADR; else new->q1.flags|=DREFOBJ;
  48.  
  49.     new->code=ASSIGN;
  50.     new->typf=UNSIGNED|CHAR;
  51.     new->q2.flags=0;
  52.     new->q2.reg=zul2ul(size);
  53.     add_IC(new);
  54. }
  55.  
  56. void add_IC(struct IC *new)
  57. /*  fuegt ein IC ein                                            */
  58. {
  59.     int code;
  60.     if(!new) return;
  61.     if(nocode) {free(new);return;}
  62.     new->next=0;
  63.     new->q1.am=new->q2.am=new->z.am=0;
  64.     code=new->code;
  65.     if(code>=BEQ&&code<=BRA) new->q1.flags=new->q2.flags=new->z.flags=0;
  66.     if(code==ALLOCREG||code==FREEREG||code==SAVEREGS||code==RESTOREREGS) new->typf=0;
  67.     if(DEBUG&64) pric2(stdout,new);
  68.     if(new->q1.flags&VAR){
  69.         if(!new->q1.v) ierror(0);
  70.         new->q1.v->flags|=USEDASSOURCE;
  71.         if(code==ADDRESS||(new->q1.flags&VARADR)) new->q1.v->flags|=USEDASADR;
  72.         new->q1.v->priority+=currentpri;
  73.     }
  74.     if(new->q2.flags&VAR){
  75.         if(!new->q2.v) ierror(0);
  76.         new->q2.v->flags|=USEDASSOURCE;
  77.         if(code==ADDRESS||(new->q2.flags&VARADR)) new->q2.v->flags|=USEDASADR;
  78.         new->q2.v->priority+=currentpri;
  79.     }
  80.     if(new->z.flags&VAR){
  81.         if(!new->z.v) ierror(0);
  82.         if(new->z.flags&DREFOBJ) new->z.v->flags|=USEDASSOURCE; else new->z.v->flags|=USEDASDEST;
  83.         new->z.v->priority+=currentpri;
  84.     }
  85.     if(/*(c_flags_val[0].l&2)&&*/code==LABEL){
  86.     /*  entfernt Spruenge zu direkt folgenden Labels    */
  87.         struct IC *p=last_ic;
  88.         while(p){
  89.             if(p->typf==new->typf&&p->code>=BEQ&&p->code<=BRA){
  90.                 struct IC *n;
  91.                 if(DEBUG&1) printf("%s l%d deleted\n",ename[p->code],p->typf);
  92.                 n=p->next;
  93.                 remove_IC(p);
  94.                 p=n;
  95.             }else{
  96.                 if(p->code!=LABEL) break;
  97.                 p=p->prev;
  98.             }
  99.         }
  100.     }
  101.     if(last_ic){
  102.         if(code==ASSIGN){
  103.             if((last_ic->z.flags&(REG|SCRATCH|DREFOBJ))==(REG|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.reg==new->q1.reg/*&&last_ic->code!=CALL*/){
  104.                 if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
  105.                     if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
  106.                     /*  verbindet op a,b->reg,move reg->c zu op a,b->c  */
  107.                     /*  hier fehlt aber noch Registerfreigabe           */
  108.                         last_ic->z=new->z;
  109.                         if(DEBUG&1) printf("move and op combined\n");
  110.                         if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  111.                             free_reg(new->q1.reg);
  112.                         free(new);
  113.                         return;
  114.                     }
  115.                 }
  116.             }
  117.             if((last_ic->z.flags&(VAR|SCRATCH|DREFOBJ))==(VAR|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.v==new->q1.v/*&&last_ic->code!=CALL*/){
  118.                 if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
  119.                     if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
  120.                     /*  verbindet op a,b->scratch,move scratch->c zu op a,b->c  */
  121.                     /*  hier fehlt aber noch Registerfreigabe           */
  122.                         last_ic->z=new->z;
  123.                         if(DEBUG&1) printf("move and op combined(2)\n");
  124. /*                        if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  125.                             free_reg(new->q1.reg);*/
  126.                         free(new);
  127.                         return;
  128.                     }
  129.                 }
  130.             }
  131.  
  132.         }
  133.         if(last_ic->code==BRA){
  134.             if(code!=LABEL&&code!=ALLOCREG&&code!=FREEREG){
  135.             /*  loescht alles nach bra bis ein Label kommt  */
  136.             /*  momentan noch nicht perfekt, da es bei alloc/freereg stoppt */
  137.                 free(new);
  138.                 if(DEBUG&1) printf("Unreachable Statement deleted\n");
  139.                 return;
  140.             }
  141.             if(last_ic->prev&&code==LABEL){
  142.             /*  ersetzt bcc l1;bra l2;l1 durch b!cc l2      */
  143.                 if(last_ic->prev->code>=BEQ&&last_ic->prev->code<=BGT&&new->typf==last_ic->prev->typf){
  144.                     if(DEBUG&1) printf("%s l%d;%s l%d; substituted\n",ename[last_ic->prev->code],last_ic->prev->typf,ename[last_ic->code],last_ic->typf);
  145.                     if(last_ic->prev->code&1) last_ic->prev->code--;
  146.                                     else      last_ic->prev->code++;
  147.                     last_ic->prev->typf=last_ic->typf;
  148.                     last_ic=last_ic->prev;
  149.                     free(last_ic->next);
  150.                     last_ic->next=new;new->prev=last_ic;
  151.                     last_ic=new;
  152.                     return;
  153.                 }
  154.             }
  155.         }
  156. /*        }*/
  157.         new->prev=last_ic;
  158.         last_ic->next=new;
  159.         last_ic=new;
  160.     }else{
  161.         last_ic=new;first_ic=new;new->prev=0;
  162.     }
  163.     ic_count++;
  164.     /*  Merken, on Fliesskomma benutzt wurde    */
  165.     if(code!=LABEL&&(code<BEQ||code>BRA))
  166.         if((new->typf&15)==FLOAT||(new->typf&15)==DOUBLE) float_used=1;
  167.     if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
  168.         free_reg(new->q1.reg);
  169.     if((new->q2.flags&SCRATCH)&&(new->q2.reg!=new->z.reg||!(new->z.flags®)))
  170.         free_reg(new->q2.reg);
  171. }
  172. void free_IC(struct IC *p)
  173. /*  Gibt IC-Liste inkl. Typen frei                  */
  174. {
  175.     struct IC *merk;
  176.     if(DEBUG&1) printf("free_IC()\n");
  177.     while(p){
  178.         if(p->q1.am) free(p->q1.am);
  179.         if(p->q2.am) free(p->q2.am);
  180.         if(p->z.am) free(p->z.am);
  181.         merk=p->next;
  182.         free(p);
  183.         p=merk;
  184.     }
  185. }
  186. void gen_IC(np p,int ltrue,int lfalse)
  187. /*  Erzeugt eine IC-Liste aus einer expression      */
  188. {
  189.     struct IC *new;
  190.     if(!p) return;
  191.     if(p->flags==STRING){
  192.     /*  hier fehlt noch die Verwaltung der String-Inhalte   */
  193.         p->o.v=add_var(empty,clone_typ(p->ntyp),STATIC,(struct const_list *)p->identifier);
  194.         p->o.v->flags|=DEFINED;
  195.         p->o.flags=VAR;
  196.         p->o.reg=0;
  197.         p->o.val=p->val;
  198.         return;
  199.     }
  200.     if(p->flags==IDENTIFIER){
  201. /*        p->o.v=find_var(p->identifier,0);*/
  202.         p->o.flags=VAR;
  203.         p->o.reg=0;
  204.         p->o.val=p->val;
  205.         return;
  206.     }
  207.     if(p->flags==CEXPR||p->flags==PCEXPR){
  208.         if(p->left){
  209.             if(p->left->flags==POSTINC) p->left->flags=PREINC;
  210.             if(p->left->flags==POSTDEC) p->left->flags=PREDEC;
  211.             gen_IC(p->left,0,0);
  212.             if(p->left->o.flags&SCRATCH) free_reg(p->left->o.reg);
  213.         }
  214.         if(p->right){
  215.             if(p->right->flags==POSTINC) p->right->flags=PREINC;
  216.             if(p->right->flags==POSTDEC) p->right->flags=PREDEC;
  217.             gen_IC(p->right,0,0);
  218.             if(p->right->o.flags&SCRATCH) free_reg(p->right->o.reg);
  219.         }
  220.         p->o.flags=KONST;
  221.         p->o.val=p->val;
  222.         p->o.reg=0;
  223.         return;
  224.     }
  225.     if(p->flags==KOMMA){
  226.         if(p->left->sidefx){
  227.             gen_IC(p->left,0,0);
  228.             if(p->left->o.flags&SCRATCH) free_reg(p->left->o.reg);
  229.         } else error(129);
  230.         gen_IC(p->right,0,0);
  231.         p->o=p->right->o;
  232.         return;
  233.     }
  234.     if(p->flags==CAST){
  235.         gen_IC(p->left,0,0);
  236.         convert(p->left,p->ntyp->flags&31);
  237.         p->o=p->left->o;
  238.         return;
  239.     }
  240.     if(p->flags==FIRSTELEMENT){
  241.         gen_IC(p->left,0,0);
  242.         p->o=p->left->o;
  243.         return;
  244.     }
  245.     new=(struct IC *)mymalloc(ICS);
  246.     new->typf=p->ntyp->flags&31;
  247.     new->q1.reg=new->q2.reg=new->z.reg=0;
  248.     new->q1.flags=new->q2.flags=new->z.flags=0;
  249.     if((p->flags>=LSHIFT&&p->flags<=MOD)||(p->flags>=OR&&p->flags<=AND)||p->flags==PMULT){
  250.         do_arith(p,new,0,0);
  251.         return;
  252.     }
  253.     if(p->flags==CONTENT){
  254.         gen_IC(p->left,0,0);
  255.         if(p->left->o.flags&VARADR){
  256.             free(new);
  257.             p->o=p->left->o;
  258.             p->o.flags&=~VARADR;
  259.             return;
  260.         }
  261.         if(!(p->left->o.flags&DREFOBJ)){
  262.             free(new);
  263.             p->o=p->left->o;
  264.             p->o.flags|=DREFOBJ;
  265.             return;
  266.         }
  267.         if(p->left->o.flags&SCRATCH){
  268.             new->z=p->left->o;
  269.             new->z.flags&=~DREFOBJ;
  270.         }else{
  271.             /*  hier muss man noch was aender, da das so nicht funktioniert */
  272.             get_scratch(&new->z,p->left->ntyp->flags,p->ntyp->flags);
  273.         }
  274.         new->code=ASSIGN;new->typf=POINTER;
  275.         new->q1=p->left->o;
  276.         new->q2.reg=sizetab[POINTER];
  277.         p->o=new->z;
  278.         add_IC(new);
  279.         p->o.flags|=DREFOBJ;
  280.         return;
  281.     }
  282.     if(p->flags==ASSIGN){
  283.         new->code=ASSIGN;
  284.         gen_IC(p->right,0,0);
  285.         gen_IC(p->left,0,0);
  286.         convert(p->right,p->ntyp->flags&31);
  287.         new->q1=p->right->o;
  288.         new->z=p->left->o;
  289.         new->q2.reg=szof(p->left->ntyp);
  290.         p->o=new->z;
  291.         add_IC(new);
  292.         return;
  293.     }
  294.     if(p->flags==ASSIGNADD){
  295.     /*  das hier ist nicht besonders schoen */
  296.         struct obj o;struct IC *n;int f;
  297.         if(p->right->right==0){
  298.         /*  sowas wie a+=0 wurde wegoptimiert   */
  299.             free(new);
  300.             p->o=p->left->o;
  301.             return;
  302.         }
  303.         f=do_arith(p->right,new,p->left,&o);
  304.         if(!f) {ierror(0);return;}
  305.         if(f>1) {ierror(0);return;}
  306.         if(!nocode&&(o.flags&(SCRATCH|REG))==(SCRATCH|REG)&&!regs[o.reg]){
  307.         /*  ueberfluessiges FREEREG entfernen   */
  308.             n=last_ic;
  309.             while(n){
  310.                 if(n->code==FREEREG&&n->q1.reg==o.reg){
  311.                     remove_IC(n);if(!nocode) regs[o.reg]=1;
  312.                     break;
  313.                 }
  314.                 n=n->prev;
  315.             }
  316.         }
  317.         convert(p->right,p->ntyp->flags&31);
  318.         new=(struct IC *)mymalloc(ICS);
  319.         new->typf=p->ntyp->flags&31;
  320.         new->q2.flags=0;
  321.         new->code=ASSIGN;
  322.         new->q1=p->right->o;
  323.         new->z=o;
  324.         new->q2.reg=szof(p->left->ntyp);
  325.         p->o=new->z;
  326.         add_IC(new);
  327.         return;
  328.     }
  329.     if(p->flags==MINUS||p->flags==KOMPLEMENT){
  330.         new->code=p->flags;
  331.         gen_IC(p->left,0,0);
  332.         convert(p->left,p->ntyp->flags);
  333.         if(regok(p->left->o.reg,p->ntyp->flags,0)&&(p->left->o.flags&SCRATCH)){
  334.             new->z=p->left->o;
  335.             new->z.flags&=~DREFOBJ;
  336.         }else{
  337.             get_scratch(&new->z,p->left->ntyp->flags,0);
  338.         }
  339.         new->q1=p->left->o;
  340.         p->o=new->z;
  341.         add_IC(new);
  342.         return;
  343.     }
  344.     if(p->flags==ADDRESS||p->flags==ADDRESSA||p->flags==ADDRESSS){
  345.         new->code=ADDRESS;
  346.         new->typf=p->left->ntyp->flags&31;
  347.         gen_IC(p->left,0,0);
  348.         if(p->left->o.flags&VAR) p->left->o.v->flags|=USEDASSOURCE|USEDASDEST;
  349.         if(p->left->o.flags&DREFOBJ){
  350.             free(new);
  351.             p->o=p->left->o;
  352.             p->o.flags&=~DREFOBJ;
  353.             return;
  354.         }
  355.         if((p->left->o.flags&VAR)&&!(p->left->o.flags&VARADR)
  356.            &&(p->left->o.v->storage_class==EXTERN||p->left->o.v->storage_class==STATIC)){
  357.             free(new);
  358.             p->o=p->left->o;
  359.             p->o.flags|=VARADR;
  360.             return;
  361.         }
  362.         new->q1=p->left->o;
  363.         get_scratch(&new->z,POINTER,p->ntyp->next->flags);
  364.         p->o=new->z;
  365.         add_IC(new);
  366.         return;
  367.     }
  368.     if(p->flags==LAND||p->flags==LOR){
  369.         int l1,l2,l3,l4;
  370. /*        printf("%s true=%d false=%d\n",ename[p->flags],ltrue,lfalse);*/
  371.         l1=++label;if(!ltrue) {l2=++label;l3=++label;l4=++label;}
  372.         if(!ltrue){if(p->flags==LAND) gen_IC(p->left,l1,l3);
  373.                     else gen_IC(p->left,l3,l1);
  374.         }else     {if(p->flags==LAND) gen_IC(p->left,l1,lfalse);
  375.                     else gen_IC(p->left,ltrue,l1);
  376.         }
  377.         if(p->left->o.flags!=0){
  378.             new->code=TEST;
  379.             new->q2.flags=new->z.flags=0;
  380.             new->typf=p->left->ntyp->flags&31;
  381.             new->q1=p->left->o;
  382.             add_IC(new);
  383.             new=(struct IC *)mymalloc(ICS);
  384.             if(p->flags==LAND) new->code=BEQ; else new->code=BNE;
  385.             if(!ltrue) new->typf=l3;
  386.             else{if(p->flags==LAND) new->typf=lfalse; else new->typf=ltrue;}
  387.             add_IC(new);
  388.         }
  389.         gen_label(l1);
  390.         if(!ltrue){if(p->flags==LAND) gen_IC(p->right,l2,l3);
  391.                     else gen_IC(p->right,l3,l2);
  392.         }else      gen_IC(p->right,ltrue,lfalse);
  393.         if(p->right->o.flags!=0){
  394.             new=(struct IC *)mymalloc(ICS);
  395.             new->code=TEST;
  396.             new->q2.flags=new->z.flags=0;
  397.             new->typf=p->right->ntyp->flags&31;
  398.             new->q1=p->right->o;
  399.             add_IC(new);
  400.             new=(struct IC *)mymalloc(ICS);
  401.             if(p->flags==LAND) new->code=BEQ; else new->code=BNE;
  402.             if(!ltrue) new->typf=l3;
  403.             else{if(p->flags==LAND) new->typf=lfalse; else new->typf=ltrue;}
  404.             add_IC(new);
  405.         }
  406.         if(!ltrue){
  407.             gen_label(l2);
  408.             if(p->flags==LAND) p->o=gen_cond(0,l3,l4); else p->o=gen_cond(1,l3,l4);
  409.         }else{
  410.             new=(struct IC *)mymalloc(ICS);
  411.             new->code=BRA;
  412.             if(p->flags==LAND) new->typf=ltrue; else new->typf=lfalse;
  413.             add_IC(new);
  414.         }
  415.         if(ltrue) p->o.flags=0;
  416.         return;
  417.     }
  418.     if(p->flags==NEGATION){
  419.         int l1,l2,l3;
  420.         if(!ltrue) {l1=++label;l2=++label;l3=++label;}
  421.         if(ltrue) gen_IC(p->left,lfalse,ltrue); else gen_IC(p->left,l1,l3);
  422.         if(!p->left->o.flags) {free(new);p->o.flags=0;
  423.         }else{
  424.             new->code=TEST;
  425.             new->q2.flags=new->z.flags=0;
  426.             new->typf=p->left->ntyp->flags&31;
  427.             new->q1=p->left->o;
  428.             add_IC(new);
  429.             new=(struct IC *)mymalloc(ICS);
  430.             new->code=BNE;
  431.             if(!ltrue) new->typf=l1; else new->typf=lfalse;
  432.             add_IC(new);
  433.         }
  434.         if(ltrue){
  435.             new=(struct IC *)mymalloc(ICS);
  436.             new->code=BRA;
  437.             if(!ltrue) new->typf=l2; else new->typf=ltrue;
  438.             add_IC(new);
  439.             p->o.flags=0;
  440.         }else{
  441.             gen_label(l3);
  442.             p->o=gen_cond(0,l1,l2);
  443.         }
  444.         return;
  445.     }
  446.     if(p->flags>=EQUAL&&p->flags<=GREATEREQ){
  447.         int l1,l2,l3,tl,tr,swapped;
  448.         if(!ltrue) {l1=++label;l2=++label;l3=++label;}
  449.         if(p->left->flags==CEXPR){
  450.         /*  Konstanten nach rechts  */
  451.             np merk;merk=p->left;p->left=p->right;p->right=merk;
  452.             swapped=1;
  453.         }else swapped=0;
  454.         new->code=COMPARE;
  455.         tl=p->left->ntyp->flags&31;tr=p->right->ntyp->flags&31;
  456.         if(p->right->flags==CEXPR&&(tr&15)<FLOAT&&(tl&15)<FLOAT){
  457.             zlong null;int negativ;
  458.             eval_constn(p->right);
  459.             null=l2zl(0L);
  460.             if(zlleq(vlong,0)) negativ=1; else negativ=0;
  461.             if(tr&UNSIGNED) negativ=0;
  462.             if((!negativ||zlleq(t_min[tl],vlong))&&(negativ||zulleq(vulong,t_max[tl]))){
  463.                 convert(p->right,tl);
  464.                 tr=tl;
  465.             }
  466.         }
  467.         if(arith(tl)&&tl!=tr){
  468.             struct Typ *t;
  469.             t=arith_typ(p->left->ntyp,p->right->ntyp);
  470.             new->typf=t->flags&31;
  471.             freetyp(t);
  472.         }else{
  473.             new->typf=p->left->ntyp->flags&31;
  474.         }
  475.         gen_IC(p->left,0,0);
  476.         convert(p->left,new->typf);
  477.         gen_IC(p->right,0,0);
  478.         convert(p->right,new->typf);
  479.         new->q1=p->left->o;
  480.         new->q2=p->right->o;
  481.         new->z.flags=0;
  482.         add_IC(new);
  483.         new=(struct IC *)mymalloc(ICS);
  484.         if(p->flags==EQUAL) new->code=BEQ;
  485.         if(p->flags==INEQUAL) new->code=BNE;
  486.         if(p->flags==LESS) {if(swapped) new->code =BGT; else new->code=BLT;}
  487.         if(p->flags==LESSEQ){if(swapped) new->code=BGE; else new->code=BLE;}
  488.         if(p->flags==GREATER){if(swapped) new->code=BLT; else new->code=BGT;}
  489.         if(p->flags==GREATEREQ){if(swapped) new->code=BLE; else new->code=BGE;}
  490.         if(ltrue) new->typf=ltrue; else new->typf=l1;
  491.         add_IC(new);
  492.         if(ltrue){
  493.             new=(struct IC *)mymalloc(ICS);
  494.             new->code=BRA;
  495.             new->typf=lfalse;
  496.             add_IC(new);
  497.             p->o.flags=0;
  498.         }else{
  499.             gen_label(l3);
  500.             p->o=gen_cond(1,l1,l2);
  501.         }
  502.         return;
  503.     }
  504.     if(p->flags==CALL){
  505.         int r,regused,sz;struct obj *op;
  506.         function_calls+=currentpri;
  507.         gen_IC(p->left,0,0);
  508.         if(!(p->left->o.flags&DREFOBJ)){
  509.             free(new);
  510.             p->o=p->left->o;
  511.             if(p->o.flags&VARADR) p->o.flags&=~VARADR;
  512.              else p->o.flags|=DREFOBJ;
  513.         }else{
  514.             if(p->left->o.flags&VARADR){
  515.                 free(new);
  516.                 p->o=p->left->o;
  517.                 p->o.flags&=~VARADR;
  518.             }else{
  519.                 if(p->left->o.flags&SCRATCH){
  520.                     new->z=p->left->o;
  521.                     new->z.flags&=~DREFOBJ;
  522.                 }else{
  523.                 /* das hier funktioniert vermutlich auch nicht  */
  524.                     get_scratch(&new->z,p->left->ntyp->flags,p->ntyp->flags);
  525.                 }
  526.                 new->code=ASSIGN;new->typf=POINTER;
  527.                 new->q1=p->left->o;
  528.                 new->q2.reg=sizetab[POINTER];
  529.                 new->q2.flags=0;
  530.                 p->o=new->z;
  531.                 add_IC(new);
  532.                 p->o.flags|=DREFOBJ;
  533.             }
  534.         }
  535. /*            p->left->o.flags-=DREFOBJ|VARADR; Was sollte das??    */
  536.         if((p->o.flags&(VAR|DREFOBJ))==VAR){
  537.             struct Var *v=p->o.v;
  538.             if(v->fi&&v->fi->first_ic){
  539.             /*  function call inlining  */
  540.                 struct argument_list *al;
  541.                 struct Var *vp,**argl1,**argl2;
  542.                 struct IC *ip;int lc;
  543.                 int arg_cnt=0,i;
  544.                 if(DEBUG&1024){
  545.                     printf("inlining call to <%s>\n",v->identifier);
  546.                     for(vp=v->fi->vars;vp;vp=vp->next)
  547.                         printf("%s(%d)\n",vp->identifier,vp->offset);
  548.                 }
  549.                 for(vp=v->fi->vars;vp;vp=vp->next){
  550.                     if(vp->offset==0&&*vp->identifier&&(vp->storage_class==AUTO||vp->storage_class==REGISTER)) arg_cnt++;
  551.                 }
  552.  
  553.                 /*  Argumente in die ersten Parametervariablen kopieren */
  554.                 argl1=mymalloc(arg_cnt*sizeof(struct Var *));
  555.                 argl2=mymalloc(arg_cnt*sizeof(struct Var *));
  556.  
  557.                 al=p->alist;vp=v->fi->vars;i=0;
  558.                 while(al){
  559.                     while(vp&&(!*vp->identifier||vp->offset!=0||(vp->storage_class!=REGISTER&&vp->storage_class!=AUTO))) vp=vp->next;
  560.                     if(!vp){ error(39); break; }
  561.                     if(i>=arg_cnt) ierror(0);
  562.                     if(DEBUG&1024) printf("arg: %s(%d)\n",vp->identifier,vp->offset);
  563.                     argl1[i]=vp;
  564.                     argl2[i]=add_var(empty,clone_typ(vp->vtyp),vp->storage_class,0);
  565.                     if(!al->arg) ierror(0);
  566.                     gen_IC(al->arg,0,0);
  567.                     convert(al->arg,vp->vtyp->flags);
  568.                     new=mymalloc(ICS);
  569.                     new->code=ASSIGN;
  570.                     new->q1=al->arg->o;
  571.                     new->q2.flags=0;
  572.                     new->q2.reg=szof(vp->vtyp);
  573.                     new->z.flags=VAR;
  574.                     new->z.val.vlong=l2zl(0L);
  575.                     new->z.v=argl2[i];
  576.                     new->typf=vp->vtyp->flags;
  577.                     add_IC(new);
  578.                     i++;
  579.                     al=al->next;
  580.                     vp=vp->next;
  581.                 }
  582.                 if(i<arg_cnt){ error(83); arg_cnt=i;}
  583.  
  584.                 /*  Kopien der Variablen erzeugen   */
  585.                 for(vp=v->fi->vars;vp;vp=vp->next){
  586.                     vp->inline_copy=0;
  587.                 }
  588.                 for(i=0;i<arg_cnt;i++){
  589.                     if(argl1[i]){
  590.                         if(!argl2[i]) ierror(0);
  591.                         argl1[i]->inline_copy=argl2[i];
  592.                     }
  593.                 }
  594.  
  595.                 /*  Rueckgabewert   */
  596.                 if((p->ntyp->flags&15)!=VOID){
  597.                     get_scratch(&p->o,p->ntyp->flags,0);
  598.                 }else{
  599.                     p->o.flags=0;
  600.                 }
  601.  
  602.                 free(argl1);
  603.                 free(argl2);
  604.  
  605.                 /*  Code einfuegen und Labels umschreiben   */
  606.                 ip=v->fi->first_ic;lc=0;
  607.                 while(ip){
  608.                     struct Var *iv;
  609.                     int c;
  610.                     new=mymalloc(ICS);
  611.                     memcpy(new,ip,ICS);
  612.                     c=ip->code;
  613.                     /*  evtl. ist ein IC praktisch ein SETRETURN, falls das */
  614.                     /*  Rueckgabeziel ueber Parameterzeiger angespr. wird   */
  615.                     if(ip->z.flags&VAR){
  616.                         iv=ip->z.v;
  617.                         if(iv->storage_class==AUTO||iv->storage_class==REGISTER){
  618.                             if(!*iv->identifier&&iv->offset==0){
  619.                                 new->z=p->o;
  620.                             }else{
  621.                                 if(!iv->inline_copy)
  622.                                     iv->inline_copy=add_var(empty,clone_typ(iv->vtyp),iv->storage_class,0);
  623.                                 new->z.v=iv->inline_copy;
  624.                             }/*else if(iv->inline_copy) ierror(0);*/
  625.                         }
  626.                     }
  627.                     /*  Kopien aller auto/register Variablen erzeugen   */
  628.                     if(ip->q1.flags&VAR){
  629.                         iv=ip->q1.v;
  630.                         if(iv->storage_class==AUTO||iv->storage_class==REGISTER){
  631.                             if(!iv->inline_copy)
  632.                                 iv->inline_copy=add_var(empty,clone_typ(iv->vtyp),iv->storage_class,0);
  633.                             new->q1.v=iv->inline_copy;
  634.                         }/*else if(iv->inline_copy) ierror(0);*/
  635.                     }
  636.                     if(ip->q2.flags&VAR){
  637.                         iv=ip->q2.v;
  638.                         if(iv->storage_class==AUTO||iv->storage_class==REGISTER){
  639.                             if(!iv->inline_copy)
  640.                                 iv->inline_copy=add_var(empty,clone_typ(iv->vtyp),iv->storage_class,0);
  641.                             new->q2.v=iv->inline_copy;
  642.                         }/*else if(iv->inline_copy) ierror(0);*/
  643.                     }
  644.                     if(c==LABEL||(c>=BEQ&&c<=BRA)){
  645.                         if(new->typf>lc) lc=new->typf;
  646.                         new->typf+=label;
  647.                     }
  648.                     if(c==SETRETURN){
  649.                         new->code=ASSIGN;
  650.                         new->z=p->o;
  651.                     }
  652.                     add_IC(new);
  653.                     ip=ip->next;
  654.                 }
  655.                 label+=lc;
  656.                 return;
  657.             }
  658.             /*  einige spezielle Inline-Funktionen; das setzt voraus, dass  */
  659.             /*  diese in den Headerfiles passend deklariert werden          */
  660.             if(!strcmp(v->identifier,"strlen")&&p->alist&&p->alist->arg){
  661.                 np n=p->alist->arg;
  662.                 if(n->flags==ADDRESSA&&n->left->flags==STRING){
  663.                     struct const_list *cl;zulong len=ul2zul(0UL);
  664.                     cl=(struct const_list *)n->left->identifier;
  665.                     while(cl){
  666.                         if(zleq(zc2zl(cl->other->val.vchar))) break;
  667.                         len=zuladd(len,ul2zul(1UL));
  668.                         cl=cl->next;
  669.                     }
  670.                     p->o.val.vulong=len;
  671.                     eval_const(&p->o.val,UNSIGNED|LONG);
  672.                     insert_const(p);
  673.                     insert_const2(&p->o.val,p->ntyp->flags);
  674.                     p->flags=CEXPR;
  675.                     p->o.flags=KONST;
  676.                     return;
  677.                 }
  678.             }
  679.  
  680.             if(INLINEMEMCPY>0&&(c_flags_val[0].l&2)){
  681.                 if(!strcmp(v->identifier,"strcpy")&&p->alist&&p->alist->next&&p->alist->next->arg){
  682.                     np n=p->alist->next->arg;
  683.                     if(n->flags==ADDRESSA&&n->left->flags==STRING){
  684.                         struct const_list *cl;zulong len=ul2zul(0UL);
  685.                         cl=(struct const_list *)n->left->identifier;
  686.                         while(cl){
  687.                             len=zuladd(len,ul2zul(1UL));
  688.                             if(zleq(zc2zl(cl->other->val.vchar))) break;
  689.                             cl=cl->next;
  690.                         }
  691.                         if(zulleq(len,ul2zul((unsigned long)INLINEMEMCPY))){
  692.                             inline_memcpy(p->alist->arg,n,len);
  693.                             p->o=p->alist->arg->o;
  694.                             return;
  695.                         }
  696.                     }
  697.                 }
  698.                 if(!strcmp(v->identifier,"memcpy")){
  699.                     if(p->alist&&p->alist->next&&p->alist->next->next
  700.                        &&p->alist->next->next->arg
  701.                        &&p->alist->next->next->arg->flags==CEXPR){
  702.                         eval_constn(p->alist->next->next->arg);
  703.                         if(zulleq(vulong,ul2zul((unsigned long)INLINEMEMCPY))){
  704.                             inline_memcpy(p->alist->arg,p->alist->next->arg,vulong);
  705.                             p->o=p->alist->arg->o;
  706.                             return;
  707.                         }
  708.                     }
  709.                 }
  710.             }
  711.         }
  712.         sz=push_args(p->alist,p->left->ntyp->next->exact,0);
  713.         /*  gegebenenfalls Adresse des Ziels auf den Stack  */
  714.         if(!freturn(p->ntyp)){
  715.             struct obj o;
  716.             new=mymalloc(ICS);
  717.             new->code=ADDRESS;
  718.             new->typf=p->ntyp->flags&31;
  719.             new->q1.flags=VAR;
  720.             new->q1.v=add_var(empty,clone_typ(p->ntyp),AUTO,0);
  721.             new->q1.val.vlong=l2zl(0L);
  722.             op=&new->q1;
  723.             new->q2.flags=0;
  724.             get_scratch(&new->z,POINTER,p->ntyp->flags&31);
  725.             o=new->z;
  726.             add_IC(new);
  727.             new=mymalloc(ICS);
  728.             new->code=PUSH;
  729.             new->typf=POINTER;
  730.             new->q1=o;
  731.             new->q2.flags=new->z.flags=0;
  732.             new->q2.reg=sizetab[POINTER];
  733.             add_IC(new);
  734.             sz+=sizetab[POINTER];
  735.         }
  736.         /*  Scratchregister evtl. sichern   */
  737.         savescratch(MOVEFROMREG,last_ic,0);
  738.         new=mymalloc(ICS);
  739.         new->code=CALL;
  740.         new->typf=FUNKT;
  741.         new->q1=p->o;
  742.         new->q2.flags=new->z.flags=0;
  743.         new->q2.reg=sz; /*  Groesse der Parameter auf dem Stack */
  744.         add_IC(new);
  745.         r=0;
  746.         if((p->ntyp->flags&15)!=VOID){
  747.             new=mymalloc(ICS);
  748.             new->code=GETRETURN;
  749.             new->q1.flags=new->q2.flags=0;
  750.             new->q1.reg=freturn(p->ntyp);
  751.             new->q2.reg=szof(p->ntyp);
  752.             new->typf=p->ntyp->flags;
  753.             if(freturn(p->ntyp)) get_scratch(&new->z,p->ntyp->flags&31,0);
  754.                 else new->z=*op;
  755.             if((new->z.flags&(REG|DREFOBJ))==REG) r=new->z.reg;
  756.             p->o=new->z;
  757.             add_IC(new);
  758.         }else{
  759.             p->o.flags=0;
  760.         }
  761.         /*  Scratchregister evtl. wiederherstellen  */
  762.         savescratch(MOVETOREG,last_ic,r);
  763.         return;
  764.     }
  765.     if(p->flags>=PREINC&&p->flags<=POSTDEC){
  766.         struct obj o;
  767.         gen_IC(p->left,0,0);
  768.         if(p->flags==POSTINC||p->flags==POSTDEC){
  769.             new=(struct IC *)mymalloc(ICS);
  770.             new->code=ASSIGN;
  771.             new->typf=p->ntyp->flags&31;
  772.             new->q2.reg=sizetab[p->ntyp->flags&15];
  773.             new->q1=p->left->o;
  774.             new->q1.flags&=~SCRATCH;
  775.             get_scratch(&new->z,p->left->ntyp->flags&31,0);
  776.             new->q2.flags=0;
  777.             o=new->z;
  778.             add_IC(new);
  779.             new=(struct IC *)mymalloc(ICS);
  780.         }else o=p->left->o;
  781.         if((p->left->ntyp->flags&15)==POINTER){
  782.             if(p->flags==PREINC||p->flags==POSTINC) new->code=ADDI2P; else new->code=SUBIFP;
  783.             vlong=l2zl((long)szof(p->left->ntyp->next));
  784.             new->q2.val.vint=zl2zi(vlong);
  785.             new->typf=INT;
  786.             new->q1=p->left->o;
  787.             new->z=p->left->o;
  788.             new->q2.flags=KONST;
  789.             add_IC(new);
  790.         }else{
  791.             if(p->flags==PREINC||p->flags==POSTINC) new->code=ADD; else new->code=SUB;
  792.             new->typf=p->ntyp->flags&31;
  793.             new->q1=p->left->o;
  794.             new->z=p->left->o;
  795.             new->q2.flags=KONST;
  796.             vlong=l2zl(1L);vulong=zl2zul(vlong);vdouble=zl2zd(vlong);
  797.             if(new->typf==CHAR) new->q2.val.vchar=zl2zc(vlong);
  798.             if(new->typf==SHORT) new->q2.val.vshort=zl2zs(vlong);
  799.             if(new->typf==INT) new->q2.val.vint=zl2zi(vlong);
  800.             if(new->typf==LONG) new->q2.val.vlong=vlong;
  801.             if(new->typf==(UNSIGNED|CHAR)) new->q2.val.vuchar=zul2zuc(vulong);
  802.             if(new->typf==(UNSIGNED|SHORT)) new->q2.val.vushort=zul2zus(vulong);
  803.             if(new->typf==(UNSIGNED|INT)) new->q2.val.vuint=zul2zui(vulong);
  804.             if(new->typf==(UNSIGNED|LONG)) new->q2.val.vulong=vulong;
  805.             if(new->typf==DOUBLE) new->q2.val.vdouble=vdouble;
  806.             if(new->typf==FLOAT) new->q2.val.vfloat=zd2zf(vdouble);
  807.             add_IC(new);
  808.         }
  809.         if(p->flags==POSTINC||p->flags==POSTDEC){
  810.             if(p->left->o.flags&SCRATCH) free_reg(p->left->o.reg);
  811.         }
  812.         p->o=o;
  813.         return;
  814.     }
  815.     if(p->flags==COND){
  816.         int ltrue,lfalse,lout;
  817.         ltrue=++label;lfalse=++label;lout=++label;
  818.         gen_IC(p->left,ltrue,lfalse);
  819.         if(!p->left->o.flags){
  820.             free(new);
  821.         }else{
  822.             if(p->left->flags!=CEXPR){
  823.                 new->code=TEST;
  824.                 new->typf=p->left->ntyp->flags&31;
  825.                 new->q1=p->left->o;
  826.                 new->q2.flags=new->z.flags=0;
  827.                 add_IC(new);
  828.                 new=(struct IC *)mymalloc(ICS);
  829.                 new->code=BEQ;
  830.                 new->typf=lfalse;
  831.                 add_IC(new);
  832.             }else{
  833.                 eval_constn(p->left);
  834.                 if(zleq(vlong)&&zuleq(vulong)&&zdeq(vdouble)){
  835.                     gen_IC(p->right->right,0,0);
  836.                     p->o=p->right->right->o;
  837.                 }else{
  838.                     gen_IC(p->right->left,0,0);
  839.                     p->o=p->right->left->o;
  840.                 }
  841.                 return;
  842.             }
  843.         }
  844.         gen_label(ltrue);
  845.         gen_IC(p->right->left,0,0);
  846.         convert(p->right->left,p->ntyp->flags&31);
  847.         if((p->right->left->o.flags&(SCRATCH|DREFOBJ))==SCRATCH){
  848.             p->o=p->right->left->o;
  849.         }else{
  850.             get_scratch(&p->o,p->ntyp->flags&31,0);
  851.             new=(struct IC *)mymalloc(ICS);
  852.             new->code=ASSIGN;
  853.             new->q1=p->right->left->o;
  854.             new->z=p->o;
  855.             new->q2.flags=0;
  856.             new->q2.reg=szof(p->ntyp);
  857.             new->typf=p->ntyp->flags&31;
  858.             p->o=new->z;
  859.             add_IC(new);
  860.         }
  861.         new=(struct IC *)mymalloc(ICS);
  862.         new->code=BRA;
  863.         new->typf=lout;
  864.         add_IC(new);
  865.         gen_label(lfalse);
  866.         gen_IC(p->right->right,0,0);
  867.         convert(p->right->right,p->ntyp->flags&31);
  868.         new=(struct IC *)mymalloc(ICS);
  869.         new->code=ASSIGN;
  870.         new->q1=p->right->right->o;
  871.         new->z=p->o;
  872.         new->q2.flags=0;
  873.         new->q2.reg=szof(p->ntyp);
  874.         new->typf=p->ntyp->flags&31;
  875.         add_IC(new);
  876.         gen_label(lout);
  877.         return;
  878.     }
  879.     printf("Operation: %d=%s\n",p->flags,ename[p->flags]);
  880.     ierror(0);
  881.     free(new);
  882.     p->o.flags=0;
  883. }
  884. int push_args(struct argument_list *al,struct struct_declaration *sd,int n)
  885. /*  Legt die Argumente eines Funktionsaufrufs in umgekehrter Reihenfolge    */
  886. /*  auf den Stack. Es wird Integer-Erweiterung vorgenommen und float wird   */
  887. /*  nach double konvertiert, falls kein Prototype da ist. Ausserdem werden  */
  888. /*  alle Argumente in ihrer Groesse aligned. Das ist evtl. nicht fuer jede  */
  889. /*  CPU ausreichend. Hier muss evtl. noch etwas getan werden.               */
  890. {
  891.     int of,t,sz;struct IC *new;
  892.     if(!al) return(0);
  893.     if(al->next) of=push_args(al->next,sd,n+1); else of=0;
  894.     if(!al->arg) {ierror(0);return(of);}
  895.     if(!sd) {ierror(0);return(of);}
  896.     gen_IC(al->arg,0,0);
  897.     if(n<sd->count){t=sd->sl[n].styp->flags;sz=szof(sd->sl[n].styp);}
  898.      else {t=al->arg->ntyp->flags;sz=szof(al->arg->ntyp);}
  899.     if((t&15)>=CHAR&&(t&15)<=LONG) {t=int_erw(t);sz=sizetab[t&15];}
  900.     if((t&15)==FLOAT&&n>=sd->count) {t=DOUBLE;sz=sizetab[t];}
  901.     convert(al->arg,t&31);
  902.     new=(struct IC *)mymalloc(ICS);
  903.     new->code=PUSH;
  904.     new->typf=t;
  905.     new->q1=al->arg->o;
  906.     new->q2.flags=new->z.flags=0;
  907.     new->q2.reg=((sz+maxalign-1)/maxalign)*maxalign;
  908.     add_IC(new);
  909.     return(of+sz);
  910. }
  911.  
  912. void convert(np p,int f)
  913. /*  konvertiert das Objekt in p->o in bestimmten Typ    */
  914. {
  915.     struct IC *new;
  916.     if((f&15)==VOID||(p->ntyp->flags&31)==f) return;
  917.     if(p->flags==CEXPR||p->flags==PCEXPR){
  918.         eval_constn(p);
  919.         p->ntyp->flags=f;
  920.         insert_const(p);
  921.         p->o.val=p->val;
  922.         return;
  923.     }
  924.     if(!must_convert(p,f)) return;
  925.     new=(struct IC *)mymalloc(ICS);
  926.     new->q1=p->o;
  927.     new->q2.flags=0;
  928.     new->code=CONVCHAR+(p->ntyp->flags&15)-CHAR;
  929.     if(p->ntyp->flags&UNSIGNED) new->code+=8;
  930.     new->typf=f;
  931.     if(!regok(p->o.reg,f,0)||!(p->o.flags&SCRATCH)){
  932.         get_scratch(&new->z,f,0);
  933.         p->o=new->z;
  934.         add_IC(new);
  935.     }else{
  936.         new->z=p->o;new->z.flags&=~DREFOBJ;
  937.         p->o=new->z;
  938.         add_IC(new);
  939.     }
  940. }
  941.  
  942. int allocreg(int f,int mode)
  943. /*  Fordert Register fuer Typ f an                      */
  944. /*  evtl. maschinenabhaengig, aber hier fehlt noch viel */
  945. /*  z.B. Eintragen eines IC                             */
  946. {
  947.     int i;struct IC *new;
  948.     if(nocode) return(1);
  949.     for(i=1;i<=MAXR;i++){
  950.         if(!regs[i]&®ok(i,f,mode)){
  951.             if(DEBUG&16) printf("alocated %s\n",regnames[i]);
  952.             regs[i]=1;regused[i]++;
  953.             new=(struct IC *)mymalloc(ICS);
  954.             new->code=ALLOCREG;
  955.             new->typf=0;
  956.             new->q1.flags=REG;
  957.             new->q1.reg=i;
  958.             new->q2.flags=new->z.flags=0;
  959.             add_IC(new);
  960.             return(i);}
  961.     }
  962.     if(DEBUG&1) printf(">%sCouldn't allocate register for type %d\n",string,f);
  963.     return(0);
  964. }
  965. void free_reg(int r)
  966. /*  Gibt Register r frei                                */
  967. /*  Eintrag eines IC fehlt noch                         */
  968. {
  969.     struct IC *new;
  970.     if(!r||nocode) return;
  971.     if(regs[r]==0) {printf("Register %s:\n",regnames[r]);ierror(0);}
  972.     if(DEBUG&16) printf("freed %s\n",regnames[r]);
  973.     new=(struct IC *)mymalloc(ICS);
  974.     new->code=FREEREG;
  975.     new->typf=0;
  976.     new->q1.flags=REG;
  977.     new->q1.reg=r;
  978.     new->q2.flags=new->z.flags=0;
  979.     add_IC(new);
  980.     regs[r]=0;
  981. }
  982. void gen_label(int l)
  983. /*  Erzeugt ein Label                                   */
  984. {
  985.     struct IC *new;
  986.     new=(struct IC *)mymalloc(ICS);
  987.     new->code=LABEL;
  988.     new->typf=l;
  989.     new->q1.flags=new->q2.flags=new->z.flags=0;
  990.     add_IC(new);
  991. }
  992. struct obj gen_cond(int m,int l1,int l2)
  993. /*  Generiert code, der 0 oder 1 in Register schreibt   */
  994. {
  995.     struct IC *new;
  996.     struct obj omerk;
  997.     new=(struct IC *)mymalloc(ICS);
  998.     new->code=ASSIGN;
  999.     new->typf=INT;
  1000.     new->q1.flags=KONST;
  1001.     new->q2.flags=0;
  1002.     new->q2.reg=sizetab[INT];
  1003.     if(!m) vlong=l2zl(1L); else vlong=l2zl(0L);
  1004.     new->q1.val.vint=zl2zi(vlong);
  1005.     get_scratch(&new->z,INT,0);
  1006.     omerk=new->z;
  1007.     add_IC(new);
  1008.     new=(struct IC *)mymalloc(ICS);
  1009.     new->code=BRA;
  1010.     new->typf=l2;
  1011.     add_IC(new);
  1012.     gen_label(l1);
  1013.     new=(struct IC *)mymalloc(ICS);
  1014.     new->code=ASSIGN;
  1015.     new->typf=INT;
  1016.     new->q1.flags=KONST;
  1017.     new->q2.flags=0;
  1018.     new->q2.reg=sizetab[INT];
  1019.     if(!m) vlong=l2zl(0L); else vlong=l2zl(1L);
  1020.     new->q1.val.vint=zl2zi(vlong);
  1021.     new->z=omerk;
  1022. /*    new->z.reg=r;
  1023.     new->z.flags=SCRATCH|REG;*/
  1024.     add_IC(new);
  1025.     gen_label(l2);
  1026.     return(omerk);
  1027. }
  1028. void scratch_var(struct obj *o,int t)
  1029. /*  liefert eine temporaere Variable                            */
  1030. /*  nicht effizient, aber wer hat schon so wenig Register...    */
  1031. {
  1032.     struct Typ *nt=(struct Typ *)mymalloc(TYPS);
  1033.     if((t&15)<CHAR||(t&15)>POINTER) ierror(0);
  1034.     nt->flags=t&31;
  1035.     if((t&15)==POINTER){
  1036.         nt->next=(struct Typ *)mymalloc(TYPS);
  1037.         nt->next->flags=VOID;
  1038.         nt->next->next=0;
  1039.     }else nt->next=0;
  1040.     o->flags=SCRATCH|VAR;o->reg=0;
  1041.     o->v=add_var(empty,nt,AUTO,0);
  1042.     o->val.vlong=l2zl(0L);
  1043. }
  1044. void get_scratch(struct obj *o,int t1,int t2)
  1045. /*  liefert ein Scratchregister oder eine Scratchvariable       */
  1046. {
  1047.     if(!(c_flags_val[0].l&2)&&(o->reg=allocreg(t1,t2))){
  1048.         o->flags=SCRATCH|REG;
  1049.     }else{
  1050.         scratch_var(o,t1);
  1051.     }
  1052. }
  1053. void remove_IC(struct IC *p)
  1054. /*  entfernt IC p aus Liste */
  1055. {
  1056.     if(p->prev) p->prev->next=p->next; else first_ic=p->next;
  1057.     if(p->next) p->next->prev=p->prev; else last_ic=p->prev;
  1058.     if(p->q1.am) free(p->q1.am);
  1059.     if(p->q2.am) free(p->q2.am);
  1060.     if(p->z.am) free(p->z.am);
  1061.     free(p);
  1062. }
  1063. int do_arith(np p,struct IC *new,np dest,struct obj *o)
  1064. /*  erzeugt IC new fuer einen arithmetischen Knoten und speichert das   */
  1065. /*  Resultat vom Unterknoten dest in o (fuer a op= b)               */
  1066. /*  liefert 0, wenn dest nicht gefunden                             */
  1067. {
  1068.     int f=0;
  1069.     new->code=p->flags;
  1070.     if(new->code==PMULT) new->code=MULT;
  1071.     gen_IC(p->left,0,0);
  1072.     if(dest&&p->left==dest) {*o=p->left->o;f++;}
  1073.     gen_IC(p->right,0,0);
  1074.     if(dest&&p->right==dest) {*o=p->right->o;f++;}
  1075.  
  1076.     if((p->left->ntyp->flags&15)==POINTER&&(p->right->ntyp->flags&15)==POINTER){
  1077.     /*  Subtrahieren zweier Pointer                                 */
  1078.         if(p->flags!=SUB) ierror(0);
  1079.         new->typf=INT;
  1080.         new->code=SUBPFP;
  1081.         new->q1=p->left->o;
  1082.         new->q2=p->right->o;
  1083.         if(!dest&&p->left->o.flags&SCRATCH&®ok(p->left->o.reg,INT,0)){
  1084.             new->z=p->left->o;
  1085.             new->z.flags&=~DREFOBJ;
  1086.         }else{
  1087.             if(USEQ2ASZ&&(p->right->o.flags&SCRATCH)&®ok(p->right->o.reg,INT,0)){
  1088.                 new->z=p->left->o;
  1089.                 new->z.flags&=(~DREFOBJ);
  1090.             }else{
  1091.                 get_scratch(&new->z,INT,0);
  1092.             }
  1093.         }
  1094.         p->o=new->z;
  1095.         add_IC(new);
  1096.         if(szof(p->left->ntyp->next)>1){
  1097.             new=(struct IC *)mymalloc(ICS);
  1098.             new->code=DIV;
  1099.             new->q1=p->o;
  1100.             new->q2.flags=KONST;
  1101.             vlong=l2zl((long)szof(p->left->ntyp->next));
  1102.             vint=zl2zi(vlong);
  1103.             new->q2.val.vint=vint;
  1104.             new->z=p->o;
  1105.             new->typf=INT;
  1106.             add_IC(new);
  1107.         }
  1108.         return(f);
  1109.     }
  1110.     if((p->flags==ADD||p->flags==SUB)&&(p->ntyp->flags&15)==POINTER){
  1111.     /*  Addieren und Subtrahieren eines Integers zu einem Pointer   */
  1112.         if(p->flags==ADD) new->code=ADDI2P; else new->code=SUBIFP;
  1113.         new->typf=p->right->ntyp->flags&31;
  1114.         new->q1=p->left->o;
  1115.         /*  kleinere Typen als MINADDI2P erst in diesen wandeln */
  1116.         if((new->typf&15)<MINADDI2P){convert(p->right,/*UNSIGNED|*/MINADDI2P);new->typf=/*UNSIGNED|*/MINADDI2P;}
  1117.         new->q2=p->right->o;
  1118.         if(!dest&&(p->left->o.flags&SCRATCH)&®ok(new->q1.reg,POINTER,p->left->ntyp->next->flags&31)){
  1119.             new->z=p->left->o;
  1120.             new->z.flags&=(~DREFOBJ);
  1121.         }else{
  1122.             get_scratch(&new->z,POINTER,p->left->ntyp->next->flags&31);
  1123.         }
  1124.         p->o=new->z;
  1125.         add_IC(new);
  1126.         return(f);
  1127.     }
  1128.     convert(p->left,p->ntyp->flags&31);
  1129.     convert(p->right,p->ntyp->flags&31);
  1130.     new->q1=p->left->o;
  1131.     new->q2=p->right->o;
  1132.     new->typf=p->ntyp->flags&31;
  1133.     /*  Bei dest!=0, d.h. ASSIGNADD, darf q1 nicht als Ziel benuzt werden!  */
  1134.     if(!dest&&(new->q1.flags&SCRATCH)&®ok(new->q1.reg,p->ntyp->flags,0)){
  1135.         new->z=new->q1;
  1136.         new->z.flags&=~DREFOBJ;
  1137.     }else{
  1138.         if((new->q2.flags&SCRATCH)&®ok(new->q2.reg,p->ntyp->flags,0)){
  1139.             if((p->flags>=OR&&p->flags<=AND)||p->flags==ADD||p->flags==MULT||p->flags==PMULT){
  1140.             /*  bei kommutativen Operatoren vertauschen     */
  1141.                 new->z=new->q2;
  1142.                 new->q2=new->q1;
  1143.                 new->q1=new->z;
  1144.                 new->z.flags&=~DREFOBJ;
  1145.             }else{
  1146.                 if(USEQ2ASZ){
  1147.                     new->z=new->q2;
  1148.                     new->z.flags&=~DREFOBJ;
  1149.                 }else{
  1150.                     get_scratch(&new->z,new->typf,0);
  1151.                 }
  1152.             }
  1153.         }else{
  1154.             get_scratch(&new->z,new->typf,0);
  1155.         }
  1156.     }
  1157.     p->o=new->z;
  1158.     add_IC(new);
  1159.     return(f);
  1160. }
  1161. void savescratch(int code,struct IC *p,int dontsave)
  1162. /*  speichert Scratchregister bzw. stellt sie wieder her (je nach code  */
  1163. /*  entweder MOVEFROMREG oder MOVETOREG)                                */
  1164. {
  1165.     int i;struct IC *new;
  1166.     for(i=1;i<=MAXR;i++){
  1167.         if(regs[i]&®scratch[i]&&i!=dontsave){
  1168.             if(!regsbuf[i]){
  1169.                 struct Typ *t;
  1170.                 if(code!=MOVEFROMREG) continue;
  1171.                 t=mymalloc(TYPS);
  1172.                 t->flags=ARRAY;
  1173.                 t->size=regsize[i];
  1174.                 t->next=mymalloc(TYPS);
  1175.                 t->next->flags=CHAR;
  1176.                 t->next->next=0;
  1177.                 regsbuf[i]=add_var(empty,t,AUTO,0);
  1178.                 regbnesting[i]=nesting;
  1179.             }
  1180.             new=mymalloc(ICS);
  1181.             new->typf=new->q2.flags=0;
  1182.             new->code=code;
  1183.             if(code==MOVEFROMREG){
  1184.                 new->q1.flags=REG;new->q1.reg=i;
  1185.                 new->z.flags=VAR;new->z.v=regsbuf[i];
  1186.                 new->z.val.vlong=l2zl(0L);
  1187.             }else{
  1188.                 new->z.flags=REG;new->z.reg=i;
  1189.                 new->q1.flags=VAR;new->q1.v=regsbuf[i];
  1190.                 new->q1.val.vlong=l2zl(0L);
  1191.             }
  1192.             insert_IC(p,new);
  1193.         }
  1194.     }
  1195. }
  1196.  
  1197.